package com.cuit.qx.service.impl;

import cn.afterturn.easypoi.entity.ImageEntity;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cuit.qx.config.BasicData;
import com.cuit.qx.entity.Config;
import com.cuit.qx.entity.ImagesVo;
import com.cuit.qx.entity.Product;
import com.cuit.qx.mapper.ProductMapper;
import com.cuit.qx.service.ConfigService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cuit.qx.service.ProductService;
import com.cuit.qx.utils.AsposeWordsUtils;
import com.cuit.qx.utils.PatternUtils;
import com.cuit.qx.utils.ReturnData;
import com.cuit.qx.utils.ReturnStateCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * <p>
 * 产品表 服务实现类
 * </p>
 *
 * @author lcj
 * @since 2021-11-23
 */
@Service
@Slf4j
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    @Resource
    private ConfigService configService;

    @Resource
    private PatternUtils patternUtils;

    @Resource
    private AsposeWordsUtils asposeWordsUtils;

    @Resource
    private ProductService productService;


    /**
     * 生成产品数据
     *
     * @param product
     * @return
     */
    @Override
    public ReturnData getProductFile(Product product) {
        //封装产品参数
        Map<String, Object> map = MapUtil.newHashMap();
        Map<String, Object> data = configService.getData();

        String productType = product.getProductType();
        //生产产品保存路径
        String productPath = data.get(BasicData.PROFILEPATH).toString();
        boolean directory = FileUtil.isDirectory(productPath);
        if (!directory) {
            FileUtil.mkdir(productPath);
        }
        //获取模板
        String templatePath = data.get(BasicData.PRODUCTFILETEMPLATEPATH).toString();
        String template = templatePath + File.separator + data.get(BasicData.TEMPLATE + productType) + BasicData.WORD;

        //获取数据库期次
        Integer period = Integer.valueOf(data.get(BasicData.TEMPLATEFILEPERIOD + productType).toString());
        product.setProductNo(period);
        Integer productMoment = product.getProductMoment();
        String s;
        switch (productType) {
            case "1":
                s = product.getStartTime() + "时" + productMoment + "时效";
                break;
            case "2":
                s = product.getStartTime() + "时" + productMoment;
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + productType);
        }
        String format = StrUtil.format(data.get(BasicData.TEMPLATEFILENAME + productType).toString(), s) + "第" + period + "期";
        product.setProductName(format);

        //产品数据入库
        period = getPeroid(product);

        String dateText = getDate(product.getStartDate(), product.getStartTime(), product.getProductMoment());

        map.put("title", product.getProductName());
        String patternText = JSONUtil.parseObj(data.get(BasicData.PATTERN + productType)).get(product.getPattern()).toString();
        map.put("pattern", patternText);
        map.put("dateText", dateText);
        map.put("content", product.getContent());
        map.put("forecast", product.getForecastUsr());
        map.put("entering", product.getEnteringUsr());
        map.put("verify", product.getVerifyUsr());
        map.put("makeuser", product.getDepartment());
        map.put("phone", data.get(BasicData.PHONE));
        //todo  获取图片


        switch (productType) {
            case "1": {
                ImageEntity image = new ImageEntity();
                image.setWidth(540);
                image.setHeight(500);
                String imagesUrl = product.getImagesPath();
                File imFile = new File(imagesUrl);
                if (!imFile.exists()) {
                    log.error("图片{}不存在", imFile);
                    removeById(product);
                    return new ReturnData(ReturnStateCode.FAILED,"本地图片"+imFile+"不存在");
                }
                image.setUrl(imagesUrl);
                map.put("image", image);
            }
            break;
            case "2": {
                String imagesJson = data.get(BasicData.IMAGESURL).toString();
                List<ImagesVo> imagesVoList = new ArrayList<>();
                JSONObject object = JSONUtil.parseObj(imagesJson);
                for (Map.Entry<String, Object> entry : object.entrySet()) {
                    ImagesVo imagesVo = new ImagesVo();
                    imagesVo.setKey(entry.getKey());
                    JSONObject obj = JSONUtil.parseObj(entry.getValue());
                    imagesVo.setName(obj.get("name").toString());
                    imagesVo.setWith(Integer.valueOf(obj.get("with").toString()));
                    imagesVo.setHeight(Integer.valueOf(obj.get("height").toString()));
                    imagesVoList.add(imagesVo);
                }

                List<String> list = new ArrayList<>(Arrays.asList(product.getImagesPath().split(";")));
                List<String> waring = new ArrayList<>();

                list.forEach(item -> {
                    File imFile = new File(item);
                    if (!imFile.exists()) {
                        log.error("图片{}不存在", imFile);
                        waring.add(imFile.getName());
                    }
                    ImagesVo imagesVo = imagesVoList.stream().filter(d -> item.contains(d.name)).findFirst().get();
                    ImageEntity image = new ImageEntity();
                    image.setHeight(imagesVo.height);
                    image.setWidth(imagesVo.with);
                    image.setUrl(item);
                    map.put(imagesVo.key, image);
                });

                if (!waring.isEmpty()){
                    removeById(product);
                    String collect = waring.stream().collect(Collectors.joining(","));
                    return new ReturnData(ReturnStateCode.FAILED,"本地图片组"+collect+"不存在");
                }

            }
            break;
        }


        File file = new File(template);
        if (!file.exists()) {
            log.error("模板文件不存在!");
            return new ReturnData(ReturnStateCode.FAILED, "产品模板不存在");
        }

        String word = productPath + File.separator + product.getProductName() + BasicData.WORD;
        String pdf = productPath + File.separator + product.getProductName() + BasicData.PDF;

        asposeWordsUtils.doc1word(map, template, word);
        asposeWordsUtils.doc2pdf(word, pdf);
        return new ReturnData(ReturnStateCode.SUCCEE, product.getProductName());
    }

    private String getDate(String startDate, String startTime, Integer productMoment) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        try {
            Date parse = sdf.parse(startDate);
            cal.setTime(parse);
        } catch (ParseException e) {
            log.error("日期转化失败");
            e.printStackTrace();
        }

        Integer startTimeNum = Integer.valueOf(startTime);

        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), startTimeNum, 0);
        cal.add(java.util.Calendar.HOUR_OF_DAY, productMoment);
        int year2 = cal.get(Calendar.YEAR);
        int month2 = cal.get(Calendar.MONTH)+1;
        int day2 = cal.get(Calendar.DAY_OF_MONTH);
        int hour2 = cal.get(Calendar.HOUR_OF_DAY);

        cal.add(java.util.Calendar.HOUR_OF_DAY, -12);
        int year1 = cal.get(Calendar.YEAR);
        int month1 = cal.get(Calendar.MONTH)+1;
        int day1 = cal.get(Calendar.DAY_OF_MONTH);
        int hour1 = cal.get(Calendar.HOUR_OF_DAY);

        String dateText = year1 + "年" + month1 + "月" + day1 + "日" + hour1 + "时至  " + year2 + "年" + month2 + "月" + day2 + "日" + hour2 + "时";
        return dateText;
    }

    @Override
    public String insertBackId(Product product) {
        this.baseMapper.insert(product);
        return product.getId();
    }

    private Integer getPeroid(Product product) {
        try {
            String id = productService.insertBackId(product);
            log.info("产品数据入库成功");
        } catch (Exception e) {
            if (e.getMessage().contains("period")) {
                //查询当前制作
                Product one = productService.getOne(new LambdaQueryWrapper<Product>()
                        .eq(Product::getProductType, product.getProductType())
                        .eq(Product::getProductNo, product.getProductNo())
                        .eq(Product::getProductMoment, product.getProductMoment())
                        .eq(Product::getStartTime, product.getStartTime())
                );
                String createTime = one.getCreateTime();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                String format = sdf.format(new Date());
                //当前时间与制作时间同一天时，覆盖原数据
                boolean equals = createTime.substring(0, format.length()).equals(format);
                if (equals) {
                    productService.removeById(one);
                } else {
                    //期次加1
                    Config config = new Config();
                    config.setConfigType(product.getProductType());
                    config.setConfigKey(patternUtils.humpToLine(BasicData.TEMPLATEFILEPERIOD));
                    int i = product.getProductNo() + 1;
                    config.setConfigContent(String.valueOf(i));
                    product.setProductNo(i);
                    boolean update = configService.update(config,
                            new LambdaQueryWrapper<Config>().eq(Config::getConfigKey, config.getConfigKey())
                                    .eq(Config::getConfigType, config.getConfigType()));
                }
                //回调生成产品数据
                getProductFile(product);
            }
        }
        return product.getProductNo();
    }


}
